package com.xwn.provider.filter;

import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.common.extension.Activate;
import com.alibaba.dubbo.rpc.*;
import com.alibaba.fastjson.JSON;
import com.xwn.bean.entity.SystemLog;
import com.xwn.bean.system.SystemAdmin;
import com.xwn.provider.dubbo.service.SystemLogService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Date;

/**
 * bubbo 系统日志拦截
 * @Author duandw
 * @Date 2019/11/1 11:28
 **/
@Activate(group = Constants.CONSUMER)
public class LogFilter implements Filter {

    protected static final Logger loggger = LoggerFactory.getLogger("dubbo");

    private SystemLogService systemLogService;

    /**
     * dubbo拦截不能使用注解@authwire 注入，使用set方法
     * @param systemLogService
     */
    public void setSystemLogService(SystemLogService systemLogService) {
        this.systemLogService = systemLogService;
    }

    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        Object args[] = invocation.getArguments();
        String argsJson = JSON.toJSONString(args);
        long start = System.currentTimeMillis();
        try {
            return invoker.invoke(invocation);
        } catch (RpcException re) {
            loggger.error(String.format("Duubo rpc error, args:[ {} ].", argsJson), re);
            throw re;
        } catch (Throwable e) {
            loggger.error(String.format("Duubo rpc error, args:[ {} ].", argsJson), e);
            throw new RpcException("Dubbo server uncaught exception!", e);
        } finally {
            long spend = (System.currentTimeMillis() - start);
            int clientPort = RpcContext.getContext().getRemotePort();
            //获取调用方IP地址
            String clientIP = RpcContext.getContext().getRemoteHost();
            //记录日志
            loggger.info(
                    "DubboRPC : API[ {} ], method[ {} ], args[ {} ], spendTime[ {} ms ], clientIp[ {} ], clientPort[ {} ].",
                    invoker.getInterface().getSimpleName(),
                    invocation.getMethodName(), argsJson, spend, clientIP,
                    clientPort);

            //持久化
            SystemLog log = systemLogService.save(new SystemLog(
                    new Date(),SystemAdmin.NAME,new Date(),SystemAdmin.NAME,
                    "PRO",invoker.getInterface().getSimpleName(),invocation.getMethodName(),
                    clientIP,invocation.getMethodName(), argsJson, spend)
            );

            if (log != null && log.getId() != null) {
                loggger.info("保存系统日志成功");
            }else{
                loggger.error("保存系统日志失败!!");
            }
        }
    }
}
